package com.wayhome.srpingbootmybatis.fileimportmanager.bo.impl;

import com.alibaba.fastjson.JSONObject;
import com.wayhome.srpingbootmybatis.async.dto.AsyncTaskAddDTO;
import com.wayhome.srpingbootmybatis.async.dto.AsyncTaskMessage;
import com.wayhome.srpingbootmybatis.async.service.AsyncTaskService;
import com.wayhome.srpingbootmybatis.config.ApiResult;
import com.wayhome.srpingbootmybatis.exception.CustomerException;
import com.wayhome.srpingbootmybatis.fileimportmanager.bo.FileImportRlstBO;
import com.wayhome.srpingbootmybatis.fileimportmanager.bo.ImportFileHandler;
import com.wayhome.srpingbootmybatis.fileimportmanager.dao.FileImportRlstDAO;
import com.wayhome.srpingbootmybatis.fileimportmanager.dto.ImportFileDTO;
import com.wayhome.srpingbootmybatis.fileimportmanager.dto.ImportFileRlstDTO;
import com.wayhome.srpingbootmybatis.fileimportmanager.dto.QImportRlstDTO;
import com.wayhome.srpingbootmybatis.fileimportmanager.enums.BusinessTypeEnums;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.util.Map;
import java.util.Objects;

@Slf4j
@Service
public class FileImportRlstBOImpl implements FileImportRlstBO {

    @Resource
    private Map<String, ImportFileHandler> importHandlerMap;

    @Resource
    private FileImportRlstDAO fileImportRlstDAO;

    @Resource
    private AsyncTaskService asyncTaskService;

    @Override
    public ApiResult saveImportFileRlst(ImportFileDTO request) throws Exception {
        checkParam(request);
        log.info("==========>进入到批量查询导入文件的接口，查询业务类型为：{}", request.getBusinessType());
        //验证是否已经写了相关业务处理器
        String businessType = request.getBusinessType();
        String handlerName = BusinessTypeEnums.getHandleByType(businessType);
        ImportFileHandler importHandler = importHandlerMap.get(handlerName);
        if (Objects.isNull(importHandler)) {
            throw new CustomerException("缺少相关业务类型的业务处理器，请联系后台管理人员");
        }
        try {
            ImportFileRlstDTO importFileRlstDTO = importHandler.doReadImportFile(request);
            log.info("==========>批量查询导入文件结果信息：{}", JSONObject.toJSONString(importFileRlstDTO));
            fileImportRlstDAO.saveFileImportRlst(importFileRlstDTO);
        } catch (Exception e) {
            log.info("=============>导入数据失败：{}", e.getMessage(), e);
            throw new CustomerException("导入数据失败：" + e.getMessage());
        }
        return ApiResult.success("导入成功");
    }

    @Override
    public void downImportRlstFile(QImportRlstDTO qImportRlstDTO) throws Exception{
        if (Objects.isNull(qImportRlstDTO)) {
            throw new CustomerException("请求参数不能为空");
        }
        if (Objects.isNull(qImportRlstDTO.getId())) {
            throw new CustomerException("要下载的上传文件结果主键不能为空");
        }
        ImportFileRlstDTO queryByPK = fileImportRlstDAO.queryByPK(qImportRlstDTO.getId());
        if (Objects.isNull(queryByPK)) {
            throw new CustomerException("未查询到相关的有效数据");
        }
        String businessType = queryByPK.getBusinessType();
        String handlerName = BusinessTypeEnums.getHandleByType(businessType);
        ImportFileHandler importHandler = importHandlerMap.get(handlerName);
        if (Objects.isNull(importHandler)) {
            throw new CustomerException("缺少相关业务类型的业务处理器，请联系后台管理人员");
        }
        String filePath = queryByPK.getFilePath();
        String fileName = queryByPK.getFileName();
        importHandler.downloadImportFile(fileName, filePath, fileName);
    }

    @Override
    public void downTemplate(QImportRlstDTO qImportRlstDTO) throws Exception {
        if (Objects.isNull(qImportRlstDTO)) {
            throw new CustomerException("请求参数不能为空");
        }
        if (StringUtils.isEmpty(qImportRlstDTO.getBusinessType())) {
            throw new CustomerException("下载模版的业务类型不能为空");
        }
        ImportFileHandler handler = getHandler(qImportRlstDTO.getBusinessType());
        handler.downloadTemplate();
    }

    @Override
    public Boolean saveAsyncTask(QImportRlstDTO qImportRlstDTO) throws Exception {
        if (Objects.isNull(qImportRlstDTO)) {
            throw new RuntimeException("请求参数不能为空");
        }
        if (Objects.isNull(qImportRlstDTO.getId())) {
            throw new RuntimeException("要下载的上传文件结果主键不能为空");
        }
        ImportFileRlstDTO queryByPK = fileImportRlstDAO.queryByPK(qImportRlstDTO.getId());
        if (Objects.isNull(queryByPK)) {
            throw new RuntimeException("未查询到相关的有效数据");
        }
        //如果有任务
        if (!StringUtils.isEmpty(queryByPK.getAsyncTaskKey())) {
            Byte taskStatus = queryByPK.getAsyncTaskStatus();
            if (0 == taskStatus || 1 == taskStatus) {
                throw new RuntimeException("任务正在执行中，请等待执行完成");
            }
            if (2 == taskStatus) {
                throw new RuntimeException("任务执行失败,可在运维的菜单中重新执行该任务");
            }
            if (3 == taskStatus) {
                throw new RuntimeException("任务已完成。无需重复执行");
            }
        }
        Integer successCnt = queryByPK.getSuccessCnt();
        if (Objects.isNull(successCnt) || queryByPK.getSuccessCnt() == 0) {
            throw new RuntimeException("没有上传成功的条数，无法生成下载任务");
        }

        Integer failCnt = queryByPK.getFailCnt();
        if (Objects.nonNull(failCnt) && failCnt > 0) {
            throw new RuntimeException("存在错误的数据，请修改完重新导入后再执行下载任务");
        }

        String businessType = queryByPK.getBusinessType();
        String taskType = BusinessTypeEnums.getTaskTypeByType(businessType);
        String taskKey = taskType + "_" + queryByPK.getId();

        AsyncTaskAddDTO asyncTaskAddDTO = new AsyncTaskAddDTO();
        asyncTaskAddDTO.setTaskKey(taskKey);
        asyncTaskAddDTO.setTaskType(taskType);
        asyncTaskAddDTO.setTaskDesc(queryByPK.getBusinessMemo());
        asyncTaskAddDTO.setJobParameter(queryByPK.getId());
        AsyncTaskMessage asyncTaskMessage = asyncTaskService.saveAsyncTask(asyncTaskAddDTO);
        //保存成功
        if (Objects.nonNull(asyncTaskMessage)) {
            queryByPK.setAsyncTaskKey(taskKey);
            queryByPK.setAsyncTaskStatus(asyncTaskMessage.getTaskStatus());
            return fileImportRlstDAO.updateImportFileRlst(queryByPK);
        }
        return Boolean.FALSE;
    }

    private void checkParam(ImportFileDTO importFileDTO) {
        if (Objects.isNull(importFileDTO)) {
            throw new CustomerException("请求参数不能为空");
        }
        if (StringUtils.isEmpty(importFileDTO.getBusinessType())) {
            throw new CustomerException("业务类型不能为空，请联系后台管理人员");
        }
        if (StringUtils.isEmpty(BusinessTypeEnums.getHandleByType(importFileDTO.getBusinessType()))) {
            throw new CustomerException("无法识别该业务类型，请联系后台管理人员");
        }
        MultipartFile file = importFileDTO.getFile();
        if (Objects.isNull(file) || file.isEmpty()) {
            throw new CustomerException("上传文件不能为空");
        }
        String originalFilename = file.getOriginalFilename();
        assert originalFilename != null;
        String fileType = originalFilename.substring(originalFilename.lastIndexOf("."));
        if (!".xls".equals(fileType) && !".xlsx".equals(fileType)) {
            throw new CustomerException("文件不是excel格式");
        }
    }

    private ImportFileHandler getHandler(String businessType) {
        String handlerName = BusinessTypeEnums.getHandleByType(businessType);
        ImportFileHandler importHandler = importHandlerMap.get(handlerName);
        if (Objects.isNull(importHandler)) {
            throw new CustomerException("缺少相关业务类型的业务处理器，请联系后台管理人员");
        }
        return importHandler;
    }

}
